﻿using KongMing.WebTools.Common;
using KongMing.WebTools.Models;
using System.Text;
using KongMing.WebTools.Contract;

namespace KongMing.WebTools.Service
{
    public class OrmBuilder
    {
        private OrmModel table;
        private StringBuilder str = new StringBuilder("");
        public OrmBuilder(OrmModel sqlTable)
        {
            table = sqlTable;
        }

        public string BuildOrmEntity()
        {
            if (!string.IsNullOrWhiteSpace(table.TableRemark))
                str.AppendRemark(table.TableRemark);
            if (table.WithOrmAttribute)
            {
                string tableAttribute = string.Empty;
                if (table.OrmType == OrmType.EFCore)
                {
                    if (table.ScanType == ExpandScanType.NoOne)
                        tableAttribute = $"[Table(\"{table.SqlTableName}\")]";
                    else if (table.ScanType == ExpandScanType.OutSofts)
                    {
                        string sqlFieldPrefix = string.IsNullOrWhiteSpace(table.SqlFieldPreFix) ? "null" : $"\"{table.SqlFieldPreFix}\"";
                        tableAttribute = $"[OutsoftsTable(\"{table.SqlTableName}\", {sqlFieldPrefix}, {(table.SqlFieldLowerCase ? "true" : "false")}, {(table.SqlFieldSplitWords ? "true" : "false")})]";
                    }
                }
                else if (table.OrmType == OrmType.SqlSugar)
                {
                    tableAttribute = $"[SugarTable(\"{table.SqlTableName}\")]";
                }
                str.AppendLineLv(tableAttribute);
            }
            string title = $"public class {table.TableName}";
            if (!string.IsNullOrWhiteSpace(table.BaseEntityName))
                title += $" : {table.BaseEntityName}";
            str.AppendLineLv(title);
            str.AppendLineLv("{");

            foreach (var field in table.Fields.Where(x => !x.IsBaseField))
            {
                if (string.IsNullOrWhiteSpace(field.FieldName))
                    continue;
                BuildOrmField(field);
            }

            str.AppendLineLv("}");
            string _str = str.ToString();
            return _str;
        }

        private void BuildOrmField(Field field)
        {
            //添加注释
            if (!string.IsNullOrWhiteSpace(field.Remark))
                str.AppendRemark(field.Remark, 2);
            if (table.WithOrmAttribute)
            {
                if (table.OrmType == OrmType.EFCore)
                    BuildEFCoreAttribute(field);
                else
                    BuildSqlSugarAttribute(field);
            }
            //c#字段
            str.AppendLineLv($"public {field.CSharpFieldType} {field.FieldName} {{ get; set; }}{field.CSharpDefaultValue}", 2);
            str.AppendLine();
        }

        /// <summary>
        /// 构建EFCore的字段特性
        /// </summary>
        private void BuildEFCoreAttribute(Field field)
        {
            if (field.IsPrimaryKey)
                str.AppendLineLv($"[Key]", 2);
            if (field.IsIdentity)
                str.AppendLineLv($"[DatabaseGenerated(DatabaseGeneratedOption.Identity)]", 2);
            string str_column = "";
            if (table.ScanType == ExpandScanType.OutSofts && !field.IsPrimaryKey && !field.IsIdentity && new string[] { SqlType.Int, SqlType.Varchar, SqlType.Nvarchar, SqlType.Decimal }.Contains(field.DataType))
            {
                string _defaultValue = field.DataType switch
                {
                    SqlType.Int => "0",
                    SqlType.Decimal => "0",
                    _ => "\"\""
                };
                str.AppendLineLv($"[FieldDefaultValue({_defaultValue})]", 2);
            }
            if(table.ScanType == ExpandScanType.NoOne)
            {
                if (field.DataType != SqlType.Int)
                    str_column = $"Column(\"{field.SqlFieldName}\", TypeName = \"{field.SqlFieldType}\")";
                else str_column = $"Column(\"{field.SqlFieldName}\")";
            }
            else if(table.ScanType == ExpandScanType.OutSofts)
            {
                if (field.DataType != SqlType.Int)
                    str_column = $"Column(TypeName = \"{field.SqlFieldType}\")";
            }
            if (!string.IsNullOrWhiteSpace(str_column))
                str.AppendLineLv($"[{str_column}]", 2);
        }

        /// <summary>
        /// 构建SqlSugar字段特性
        /// </summary>
        private void BuildSqlSugarAttribute(Field field)
        {
            string sugar_length = "";
            if (field.DataType == SqlType.Decimal)
            {
                var arr = field.Length.Split(',');
                if (arr.Length == 2)
                    sugar_length = $"Length = {arr[0]}, DecimalDigits = {arr[1]}, ";
                else
                    sugar_length = "Length = 18, DecimalDigits = 2, ";
            }
            else if (field.DataType == SqlType.Varchar || field.DataType == SqlType.Nvarchar)
            {
                sugar_length = $"Length = {field.Length}, ";
            }
            string sugar_pk = field.IsPrimaryKey ? "IsPrimaryKey = true, " : "";
            string sugar_identity = field.IsIdentity ? "IsIdentity = true, " : "";
            string sugar_isnullable = field.IsNullable ? "IsNullable = true, " : "";
            string sugar_defaultValue = field.SqlDefaultValue == null ? "" : (new string[] { "varchar", "nvarchar", "text" }.Contains(field.DataType) ? $"DefaultValue = \"'{field.SqlDefaultValue}'\", " : $"DefaultValue = \"{field.SqlDefaultValue}\", ");
            string sugar_dataType = $"ColumnDataType = \"{field.DataType}\"";
            str.AppendLineLv($"[SugarColumn({sugar_length}{sugar_pk}{sugar_identity}{sugar_isnullable}{sugar_defaultValue}{sugar_dataType})]", 2);
        }
    }
}
